package com.gwl.concurrent.lock;

import static java.lang.System.out;

import java.util.concurrent.TimeUnit;

class NeedsCleanup { 
	private final int id; 
	public NeedsCleanup(int ident) { 
		id = ident; 
		out.println("NeedsCleanup:" + id); 
	} 
	public void cleanup() { 
		out.println("clean up:" + id); 
	}
} 
class Blocked3 implements Runnable {
	private volatile double d = 0.0; 
	@Override
	public void run() {
		try {
			while(!Thread.interrupted()) { 
				//point 1
				NeedsCleanup n1 = new NeedsCleanup(1); 
				try {
					out.println("Sleeping"); 
					TimeUnit.SECONDS.sleep(1); 
					//point 2
					NeedsCleanup n2 = new NeedsCleanup(2); 
					try { 
						out.println("Calculating" + System.currentTimeMillis()); 
						for(int i=1; i<300000000; i++)  
							d = d + (Math.E + Math.PI) / d; 
						out.println("Finished time-consuming operation" + System.currentTimeMillis()); 
					} finally { 
						n2.cleanup(); 
					}
				} finally { 
					n1.cleanup(); 
				}
			}
			out.println("exiting via while() test"); 
		} catch (InterruptedException e) {
			out.println("exiting via InterruptedException"); 
		} 
	} 
	
}
public class InterruptingIdiom {
	public static void main(String[] args) throws NumberFormatException, InterruptedException {
		if(args.length != 1) { 
			out.println("usage: java InterruptingIdiom-in-mS"); 
			System.exit(1); 
		} 
		Thread t = new Thread(new Blocked3()); 
		t.start(); 
		TimeUnit.MILLISECONDS.sleep(Integer.valueOf(args[0])); 
		out.println("interrupt"); 
		t.interrupt(); 
	}

}
